package com.dly.hope.service.impl;

import com.dly.hope.constant.ExceptionConstant;
import com.dly.hope.constant.GlobalException;
import com.dly.hope.modle.ValidateCode;
import com.dly.hope.repository.ValidateCodeRepository;
import com.dly.hope.service.ValidateCodeService;
import com.dly.hope.type.DataStatusEnum;
import com.dly.hope.utils.ExceptionPropertiesUtil;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Date;

/**
 * @author linyu.dai
 * @project myserve
 * @description
 * @creat 2022/8/28 20:12:39
 */
@Service
public class ValidateCodeServiceImpl implements ValidateCodeService {

    @Resource
    private ValidateCodeRepository validateCodeRepository;

    @Value("${email.expired}")
    private Integer expired;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ValidateCode saveValidateCode(String email) {
        ValidateCode validateCode = new ValidateCode();
        validateCode.setCode(RandomStringUtils.random(6,false,true));
        validateCode.setEmailTo(email);
        return validateCodeRepository.save(validateCode);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void checkCode(String email, String code) {
        validateCodeRepository.findByEmailToAndUseAndSendAndDataStatus(email, DataStatusEnum.NO_USER.getCode(),true,DataStatusEnum.EFFICIENT.getCode()).map((validateCode -> {
            if(DateUtils.addSeconds(validateCode.getCreateDate(), expired).before(new Date())){
                //删除过期验证码
                deleteValidateCode(validateCode);
                throw ExceptionPropertiesUtil.getException(ExceptionConstant.VALIDATE_CODE_EXPIRED);
            }

            if(!code.equals(validateCode.getCode())){
                throw ExceptionPropertiesUtil.getException(ExceptionConstant.VALIDATE_CODE_ERROR);
            }
            //设置使用时间
            validateCode.setUsedDate(new Date());
            validateCode.setUse(DataStatusEnum.IS_USER.getCode());
            return true;
        })).orElseThrow(()->ExceptionPropertiesUtil.getException(ExceptionConstant.VALIDATE_CODE_NO_SEND));
    }

    /**
     * 删除过期验证码
     */
    private void deleteValidateCode(ValidateCode validateCode){
        validateCode.setDataStatus(DataStatusEnum.INVALID.getCode());
        validateCodeRepository.save(validateCode);
    }
}
